package codec;

import entity.RpcRequest;
import entity.RpcResponse;
import enumeration.PackageType;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import serializer.Serializer;

/*
 * 自定义编码器   object -> bytebuf
 * 自定义协议格式
 * magicType: 魔数 int
 * 包类型 pacgetype：请求/响应 int
 * 序列化类型：serializer.code int
 * 数据长度 length：tcp 粘包 半包问题 int
 * 数据 data: 储存实际数据。
 +---------------+---------------+-----------------+-------------+
|  Magic Number |  Package Type | Serializer Type | Data Length |
|    4 bytes    |    4 bytes    |     4 bytes     |   4 bytes   |
+---------------+---------------+-----------------+-------------+
|                          Data Bytes                           |
|                   Length: ${Data Length}                      |
+---------------------------------------------------------------+
 * */
public class CommonEncoder extends MessageToByteEncoder {
    private static final Logger logger = LoggerFactory.getLogger(CommonEncoder.class);
    private final int MAGIC_TYPE = 0xCAFEBABE;
    private Serializer serializer;

    public CommonEncoder(Serializer serializer) {
        this.serializer = serializer;
    }

    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, Object msg, ByteBuf out) throws Exception {
        out.writeInt(MAGIC_TYPE);
        //出站判断 类型？
        if (msg instanceof RpcRequest) {
            out.writeInt(PackageType.REQUEST_PACK.getCode());
        } else if (msg instanceof RpcResponse) {
            out.writeInt(PackageType.RESPONSE_PACK.getCode());
        }
        //msg -> out object -> bytebuf
        //序列化类型
        out.writeInt(serializer.getCode());
        //数据长度+数据
        byte[] bytes = serializer.serialize(msg);
        logger.info("编码成功");
        out.writeInt(bytes.length);
        out.writeBytes(bytes);
    }
}
